package com.jcl.recruit.wechat.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jcl.recruit.core.config.SystemConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class WeixinUtils {

    private static final Logger logger = LoggerFactory.getLogger(WeixinUtils.class);

    public static String login_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URL&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
    // 网页授权登陆code 请求
    private static String get_code_access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    // access_token
    private static String get_access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
    // 刷新access_token
    private static String get_refresh_token_url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
    // 验证 access_token
    private static String get_validate_access_token_url = "https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID";
    // 需要缓存 jsapi_ticket
    private static String get_jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
    // 获取登录时临时用户的简单信息
    private static String get_userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
    // 获取用户基本信息
    private static String get_userbaseinfo_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
    // 发送模板消息
    private static String post_template_url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";

    private static final String  HTTP_POST_METHOD              = "POST";
    private static final String  HTTP_GET_METHOD               = "GET";
    public static final String   JSON_ERROR_CODE               = "errcode";
    public static final String   JSON_ERROR_MSG                = "errmsg";
    public static final String   JSON_OK                       = "ok";
    public static final String   ERROR_CODE_42001              = "42001";
    public static final String   ERROR_CODE_41001              = "41001";


    public static String getAccessToken(){
        JSONObject jsonObj = accessTokenJson();
        String accessToken = null == jsonObj.getString("access_token") ? null : jsonObj.getString("access_token");
        return accessToken;
    }

    private static JSONObject accessTokenJson(){
        String url = get_access_token_url.replaceAll("APPID", SystemConfig.getSystemWechatAppid())
                .replaceAll("SECRET", SystemConfig.getSystemWechatAppsecret());
        return getMessage(url, HTTP_GET_METHOD);
    }

    public static String ticket(String access_token) {
        String url = get_jsapi_ticket_url.replaceAll("ACCESS_TOKEN", access_token);
        JSONObject jsonObj = getMessage(url, HTTP_GET_METHOD);
        return null == jsonObj.getString("ticket") ? null : jsonObj.getString("ticket");
    }

    public static String getWechatLoginUrl(String appId, String redirectUrl, String state) {
        String url = login_url.replaceAll("APPID", appId)
                .replaceAll("REDIRECT_URL", redirectUrl)
                .replaceAll("STATE", state);

        return url;
    }

    public static JSONObject getUserInfoObjectJson(String access_token, String openid) {

        String url = get_userinfo_url.replaceAll("ACCESS_TOKEN", access_token)
                .replaceAll("OPENID", openid);

        return getMessage(url, HTTP_GET_METHOD);
    }

    public static JSONObject getCodeObjectJson(String code) {

        String url = get_code_access_token_url.replaceAll("APPID", SystemConfig.getSystemWechatAppid())
                .replaceAll("SECRET", SystemConfig.getSystemWechatAppsecret()).replaceAll("CODE", code);

        return getMessage(url, HTTP_GET_METHOD);
    }

    public static JSONObject getUserBaseInfoObjectJson(String access_token, String openid) {

        String url = get_userbaseinfo_url.replaceAll("ACCESS_TOKEN", access_token)
                .replaceAll("OPENID", openid);

        return getMessage(url, HTTP_GET_METHOD);
    }

    public static JSONObject sendTemplateMessageJson(String access_token, String sendMessage){
        String url = post_template_url.replaceAll("ACCESS_TOKEN", access_token);
        logger.info("send template message is : {}", sendMessage);
        JSONObject json = null;
        try {
            Thread.sleep(2000);
            String message = sendMessage(url, sendMessage);
            json = JSON.parseObject(message);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return json;
    }

    public static JSONObject refreshToken(String access_token) {

        String url = get_refresh_token_url.replaceAll("ACCESS_TOKEN", access_token)
                .replaceAll("APPID", SystemConfig.getSystemWechatAppid());

        return getMessage(url, HTTP_GET_METHOD);
    }

    public static JSONObject validateAccessToken(String access_token, String openid) {

        String url = get_validate_access_token_url.replaceAll("ACCESS_TOKEN", access_token)
                .replaceAll("OPENID", openid);

        return getMessage(url, HTTP_GET_METHOD);
    }

    /**
     * 发送消息
     *
     * @param url
     * @param paramData
     * @return
     */
    private static String sendMessage(String url, String paramData) {

        try {
            URL _url = new URL(url);
            HttpURLConnection http = (HttpURLConnection) _url.openConnection();
            http.setRequestMethod(HTTP_POST_METHOD);
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            http.connect();
            OutputStream os = http.getOutputStream();
            os.write(paramData.getBytes("UTF-8"));
            os.flush();
            os.close();

            InputStream ins = http.getInputStream();
            byte[] bytes = new byte[ins.available()];
            ins.read(bytes);
            ins.close();
            String message = new String(bytes, "UTF-8");
            logger.info("wechat send message : {}", message);
            return message;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取消息
     *
     * @param url
     * @param type
     * @return
     */
    private static JSONObject getMessage(String url, String type) {

        if (StringUtils.isEmpty(type)) {
            type = HTTP_GET_METHOD;
        }
        try {
            URL getUrl = new URL(url);
            HttpURLConnection http = (HttpURLConnection) getUrl.openConnection();
            http.setRequestMethod(type);
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            http.connect();

            InputStream ins = http.getInputStream();
            byte[] bytes = new byte[ins.available()];
            ins.read(bytes);
            ins.close();
            String message = new String(bytes, "UTF-8");
            logger.info("wechat get message : {}", message);
            return JSON.parseObject(message);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
